/**************************************************************************
 * @doc TRAN
 * @module AUTOSTTL.C |
 * Source file for the Auto Settlement functions.
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team (I_SP2000).
 * <nl>Notes       :
 *
 * @head3 TRAN |
 * @index | TRAN
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
$Log: /SoftPay/SPK2SIM/Source/Tran/AutoSttl.c $
 ********************************************************************************/
#include <project.h>

#ifdef BATCH_DEFINED

//#include <beetle.h>
//#include <beetleplug.h>

#include <message.h>
#include <applidl.h>
#include <aclconio.h>
#include <acldev.h>
#include <aclstr.h>
#include <string.h>
#include <svc.h>
#include <varrec.h>


/** /#define DEBUG_AUTOSTTL*/
#ifdef DEBUG_AUTOSTTL
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <gds.h>
#include <sizes.h>
#include <msg.h>
#include <batmsg.h>
#include <msgfuncs.h>
#include <tblutil.h>
#include <settle.h>
#include <date.h>
#include <menufunc.h>
#include <menus.h>
#include <mdlfuncs.h>
#include <ui.h>
#include <entry.h>
#include <oper.h>
#include <spdebug.h>
#include <logo.h>
#include <confio.h>
#include <operate.h>
#include <pbatch.h>
#include <batch.h>
#include <mem.h>

#include <autosttl.h>
#include <confproto.h>

/*********************************************************************************************
* @func void | vdResetAutoSettleData |
*       Sets the AST data file to original values
*
* @parm AST_REC * | psrAST |
*       Auto Settle structure.
*
* @end
**********************************************************************************************/

void vdResetAutoSettleData(AST_REC* psrAST) {
    psrAST->szAdjustedSettleTime[0] = '\0';
    pad(psrAST->szAdjustedSettleTime, psrAST->szAdjustedSettleTime, '0', DATE_SIZE + TIME_SIZE, LEFT);
    psrAST->inRetryCounter = 0;
    psrAST->inMerchantRecordNumber = 0;
    if ((inSaveConfRec(AST_FILE_NAME, SIZE_AST_REC, 0, (char *) psrAST)) != VS_SUCCESS)
        vdDisplayMessageFromFile(AST_ERR_MSG21, WARNING_MSG);
}

/*********************************************************************************************
* @func void | vdSetAllMITrecords |
*       Sets all the records in the MIT file with a new settle date
*
* @parm char * | pszDate |
*       Teminal date.
*
* @end
**********************************************************************************************/
void vdSetAllMITRecords(char* pszDate,int inRecord) {
    /**/pdebug(("vdSetAllMITRecords"));/**/

    vdSetAutoSettDate(pszDate);
    if ((inSaveMITRec(inRecord)) != VS_SUCCESS)
        vdDisplayMessageFromFile(MIT_ERR_MSG21, WARNING_MSG);
}

/*********************************************************************************************
* @func void | vdAdjustAutoSettleTime |
*       Modifies the auto settlement time base on the wait time from the TCT
*
* @parm char * | pszTime |
* @parm char * | pszDate |
*       Teminal time.
*
* @parm AST_REC * | psrAST |
*       Auto Settle structure.
*
* @end
**********************************************************************************************/

void vdAdjustAutoSettleTime(char* pszTime,char* pszDate,AST_REC* psrAST) {
    char szTime[TIME_SIZE + 1];
    int inMinutes;
    int inHours;
    int inYear;
    int inMonth;
    int inDay;

    char szDate[DATE_SIZE + 1];

    MEMCLR(szTime, sizeof(szTime));
    strncpy(szTime, pszTime, TIME_SIZE);


    inHours = strn2int(szTime, 2);
    inMinutes = strn2int(&szTime[2], 2);
    inYear = strn2int(&pszDate[4], 2);
    inMonth = strn2int(pszDate, 2);
    inDay = strn2int(&pszDate[2], 2);

    inMinutes += inGetAutoSttlWaitTime();
    while (inMinutes >= 60) {
        inMinutes -= 60;
        inHours++;
    }

    if (inHours > 23) {
        inHours -= 24;
        inDay++;
    }

    int2str(szDate, inYear);
    pad(szDate, szDate, '0', 2, RIGHT);
    int2str(&szDate[2], inMonth);
    pad(&szDate[2], &szDate[2], '0', 2, RIGHT);
    int2str(&szDate[4], inDay);
    pad(&szDate[4], &szDate[4], '0', 2, RIGHT);

    strncpy(psrAST->szAdjustedSettleTime, szDate, DATE_SIZE);

    int2str(szTime, inHours);
    pad(szTime, szTime, '0', 2, RIGHT);
    int2str(&szTime[2], inMinutes);
    pad(&szTime[2], &szTime[2], '0', 2, RIGHT);
    pad(szTime, szTime, '0', TIME_SIZE, LEFT);

    strncpy(&psrAST->szAdjustedSettleTime[DATE_SIZE], szTime, TIME_SIZE);
    psrAST->inRetryCounter++;

    if ((inSaveConfRec(AST_FILE_NAME, SIZE_AST_REC, 0, (char *) psrAST)) != VS_SUCCESS)
        vdDisplayMessageFromFile(AST_ERR_MSG21, WARNING_MSG);
}

/*********************************************************************************************
* @func VB_BOOL | fAutoSettleTime |
*       Checks the auto settle time for each merchant. If there is a merchant that has
*       not been settle and settle time has past. The function returns TRUE.
*
* @parm char * | pszTime |
*       Teminal time.
*
* @parm char * | pszDate |
*       Teminal date.
*
* @parm AST_REC * | psrAST |
*       Auto Settle structure.
*
* @rdesc return values.
* @flag int    |  VS_TRUE
* @flag int    |  VS_FALSE
* @end
**********************************************************************************************/
VS_BOOL fAutoSettleTime(char* pszTime,char* pszDate,AST_REC* psrAST) {
    char szSettTime[TIME_SIZE + 1];
    char szCurrDateTime[DATE_SIZE + TIME_SIZE + 1];

    /**/pdebug(("fAutoSettleTime"));/**/

    strlcpy(szCurrDateTime, &pszDate[4], 2);
    strlcpy(&szCurrDateTime[2], pszDate, 4);
    strlcpy(&szCurrDateTime[6], pszTime, TIME_SIZE);

    if (psrAST->inRetryCounter != 0) {
        if ((strncmp(szCurrDateTime, psrAST->szAdjustedSettleTime, 10)) < 0)
            return (VS_FALSE);
        else
            return (VS_TRUE);
    }

    strlcpy(szSettTime, szGetAutoSettTime(), TIME_SIZE);

    if ((strncmp(szSettTime, "999999", TIME_SIZE)) == 0) /* Merchant does not auto settle */
        return(VS_FALSE);

    /* If the MIT settle date is same as the terminal date the merchant has
       already settled */
    if ((strncmp(pszDate, szGetAutoSettDate(), DATE_SIZE)) != 0)
        if ((strncmp(pszTime, szSettTime, TIME_SIZE - 2)) >= 0) {
            psrAST->inMerchantRecordNumber = inGetMITIndex();
            return(VS_TRUE);
        }

    return(VS_FALSE);
}

/*********************************************************************************************
* @func int | inCheckAutoSettle |
*       Checks TCT auto time and proceeds with settlement if
*       time is equal and prompt for auto settle continue times out
*       or answer is yes.
*
* @rdesc return values.
* @flag int    |  VS_ERR
* @flag int    |  VS_SUCCESS
* @end
**********************************************************************************************/

int inCheckAutoSettle() {
    int intries = -1;
    signed int inRetVal = VS_FAILURE;
    int inRetSettleVal = 99;
    int inResult;
    char szDate[DATE_SIZE + 1];
    char szTime[TIME_SIZE + 1];
    AST_REC srASTRec;
    TRANSACTION_OBJECT obTran;
    int inRecord;
    char szSettleMsg[30];
    int inOpenTabsExist = VS_FALSE;
    char* chNull = 0;
    unsigned char * pucTempFlexiData;

    memset((char *) &obTran, 0x00, sizeof(TRANSACTION_OBJECT));

    if ((inLoadConfRec(AST_FILE_NAME, SIZE_AST_REC, 0, (char *) &srASTRec)) != VS_SUCCESS) {
        srASTRec.szAdjustedSettleTime[0] = '0';
        pad(srASTRec.szAdjustedSettleTime, srASTRec.szAdjustedSettleTime, '0', DATE_SIZE + TIME_SIZE, LEFT);
        srASTRec.inRetryCounter = 0;
    }

    pstGetSet_pobTran(&obTran, 1, &inResult); /* set the address */
    if (inResult == VS_ERR)
        return VS_ERR;


    // Don't know why we can't alloc the batch flexi here but it causes
    // a System Error Restart in multi-merchant mode when the settlement
    // fails and it retries three times (actually on the next sale after)
    // However, it seems to work w/out it so go figure ?


    // Need the obTran flexi record for Amex PIP
    if ((obTran.pchFlexiData = (unsigned char *) pchAlloc(MAX_TRAN_FLEXI_REC_SIZE)) == NULL_CH) {
        pdebug(("Tran Flexi Alloc Fail"));
        return VS_ERR;
    }

    vVarInitRecord(obTran.pchFlexiData, MAX_TRAN_FLEXI_REC_SIZE, 0);

    pucTempFlexiData = obTran.pchFlexiData;
    //pucTempHostData = obTran.srBRec.pchHostData;

    // merchant loop
    for (inRecord = 0; inRecord < inGetMITTotRecs(); inRecord++) {
        intries = -1;
        vdGetDate(szDate, MMDDYY);
        vdGetTime(szTime);

        // Need to clean out obTran for each merchant but we have pointers
        // to dynamic data so we need to save off the pointers (outside of loop)
        // then clear obTran, reassigned the pointers and clear out the flexi data
        memset((char *) &obTran, 0x00, sizeof(TRANSACTION_OBJECT));
        obTran.pchFlexiData = pucTempFlexiData;
        vVarInitRecord(obTran.pchFlexiData, MAX_TRAN_FLEXI_REC_SIZE, 0);

        obTran.fAutoSettle = VS_TRUE ;
        strlcpy(obTran.szSettTime, szTime, DATE_SIZE);
        strlcpy(obTran.szSettDate, szDate, DATE_SIZE);
        if (inLoadMITRec(inRecord) != VS_SUCCESS) {
            vdDisplayMessageFromFile(MIT_ERR_MSG21, WARNING_MSG);
            pstGetSet_pobTran(&obTran, 2, &inResult);
            vdFree((char *) obTran.pchFlexiData);
            return (VS_FALSE);
        }
        /*
         *      Added from inInitOper() for initialization
         */

        if (fAutoSettleTime(szTime, szDate, &srASTRec)) {
            disable_hot_key();
            clrscr();
            vdSetActionFont();
            inRetVal = obDisp.inDO_ChooseOne(chNull, (char *) pchGetMsg(AUTOSTTL_CONT_MSG15), (char *) pchGetMsg(YESNO_MSG5x), 2, NULL_PFI);
            if (inRetVal == KEY_NO) {
                if (srASTRec.inRetryCounter < inGetAutoSettRetries())
                    vdAdjustAutoSettleTime(szTime, szDate, &srASTRec);
                else {
                    vdDisplayMessageFromFile(AUTOSTTL_ABORT_MSG21, WARNING_MSG);
                    vdResetAutoSettleData(&srASTRec);
                    vdSetAllMITRecords(szDate, inRecord);
                }
                pstGetSet_pobTran(&obTran, 2, &inResult);
                vdFree((char *) obTran.pchFlexiData);
                enable_hot_key();
                return(VS_SUCCESS);
            } /* end if choose one = NO */


            if (inSettleOpenTabs(&obTran) != VS_SUCCESS) {
                /**/pdebug(("inSettleOpenTabs"));/**/
                /* Set power failure recovery state */
                //              inPFRStateStoreAll(PFR_IDLE_STATE,&obTran,0,0);
                if (fGetOTabSettle() == VS_FALSE)
                    inOpenTabsExist = VS_TRUE;
                vdCloseTabBatch(&obTran);
            }


            if (fChkAllHostBatches(&obTran)) {
                vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
                /* Need the below two flags like this so idle is redisplayed */
                inRetSettleVal = VS_ERR;
                inRetVal = VS_SUCCESS;
            }

            // fChkAllHostBatches() above reset our MIT and we need it
            // correct for inSettleUnadjTipsFunction() and pSettleAllHosts()
            if (inLoadMITRec(inRecord) != VS_SUCCESS) {
                vdDisplayMessageFromFile(MIT_ERR_MSG21, WARNING_MSG);
                pstGetSet_pobTran(&obTran, 2, &inResult);
                vdFree((char *) obTran.pchFlexiData);
                return (VS_FALSE);
            }

            if (fGetDemoMode() && !fGetTrainSettle())
                vdDisplayNoSettleMsg(TRAINING_DEMO_MODE_MSG21);
            else if (inOpenTabsExist) {
                vdGetMessageFromFile(OPEN_TABS_EXIST_MSG21, szSettleMsg);
                strlcpy(obTran.szRespMsg, szSettleMsg, RESP_MSG_SIZE);
                inPrintSettlementReport(&obTran, VS_FALSE, VS_FALSE, VS_FALSE);
                strlcpy(obTran.szRespMsg, "", RESP_MSG_SIZE);
                inOpenTabsExist = VS_FALSE;
                /* Need the below two flags like this so idle is redisplayed */
                inRetSettleVal = VS_ERR;
                inRetVal = VS_SUCCESS;
            } else if (inSettleUnadjTipsFunction(&obTran) == VS_ESCAPE) {
                vdGetMessageFromFile(UNADJUST_TIPS_EXIST_MSG21, szSettleMsg);
                strlcpy(obTran.szRespMsg, szSettleMsg, RESP_MSG_SIZE);
                inPrintSettlementReport(&obTran, VS_FALSE, VS_FALSE, VS_FALSE);
                strlcpy(obTran.szRespMsg, "", RESP_MSG_SIZE);
                /* Need the below two flags like this so idle is redisplayed */
                inRetSettleVal = VS_ERR;
                inRetVal = VS_SUCCESS;
            } else {
                vdDisplayTitle(SETTLE_MSG21, RIGHT_JUSTIFY);
                while (intries < inGetAutoSettRetries()) {
                    //op code is set for the sync comm which gets the phone number
                    //based on this value
                    obTran.inOperationCode = SETTLE_OPERATION;
                    if ((inRetSettleVal = pSettleAllHosts(&obTran)) == VS_SUCCESS) {
                        inRetVal = VS_SUCCESS;
                        break;
                    }
                    if (inRetSettleVal == VS_ESCAPE) {
                        /* added call from SPBASE2.5 09/23/99 gw */
                        vdDisplayNoSettleMsg(srGDS.lnErrorMessageIndex);
                        inRetVal = VS_ESCAPE;
                        break;
                    }
                    intries++;
                }
            } /* end else settle */


            // Reload correct MIT record incase pSettleAllHosts() has
            // loaded another.
            if (inLoadMITRec(inRecord) != VS_SUCCESS) {
                vdDisplayMessageFromFile(MIT_ERR_MSG21, WARNING_MSG);
                pstGetSet_pobTran(&obTran, 2, &inResult);
                vdFree((char *) obTran.pchFlexiData);
                return (VS_FALSE);
            }

            vdSetAutoSettDate(szDate);
            if ((inSaveMITRec(inRecord)) != VS_SUCCESS)
                vdDisplayMessageFromFile(MIT_ERR_MSG21, WARNING_MSG);
            vdResetAutoSettleData(&srASTRec);

            enable_hot_key();
        } /* end if AutoSettleTime */

#ifdef BATCH_DEFINED

        /* Close Batch if it has been opened, close it */
        vdCloseDCBatch(&obTran);
        vdCloseTabBatch(&obTran);

#endif // BATCH_DEFINED
    }//end merchant loop

    /* if no settlement was attempted then do not redo idle screen */
    pstGetSet_pobTran(&obTran, 2, &inResult);
    vdFree((char *) obTran.pchFlexiData);
    if (inRetSettleVal == 99)
        inRetVal = VS_ERR;

    return(inRetVal);
} /* end func inCheckAutoSettle() */


/*********************************************************************************************
* @func int | inIdleAutoSettle |
*       Called from the idle loop to Check autosettle flag.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction object.
*
* @rdesc return values.
* @flag int    |  VS_ERR
* @flag int    |  VS_SUCCESS
* @end
**********************************************************************************************/

int inIdleAutoSettle(TRANSACTION_OBJECT* pobTran) {
    int inRetVal;

    /*
     *      Check for AUTO-SETTLE activity
     */
    if (fGetAutoSettle()) {
        if ((inRetVal = inCheckAutoSettle()) == VS_FAILURE) {

            vdDispMsgAt(SETTLE_FAIL_ERR_MSG, obDisp.inHomeCol, obDisp.inInputLine, CLR_EOL);
            vdDisplayMessageFromFile(CLEAR_TO_CONTINUE_MSG, ERROR_MSG);
        }
        if (inRetVal == VS_ESCAPE)
            vdSetMenuFont();
        else if (inRetVal != VS_ERR) {
            vdFlushKeyboardBuffer();
            vdSetMenuFont();
            fDisplayLogoNow = VS_TRUE;
            vdSelectMenu(ROOT_MENU_ID);
            enable_hot_key();
        }
    }
    return(VS_SUCCESS);
}

#endif // BATCH_DEFINED
